package body ariane.maths.vector is

  -- creates an object and initializes it with specified data
  function create(components : components_t := (others=>zero))
                  return object is
    o : object;
  begin
    o.set(components);
    return o;
  end create;

  -- initializes a vector object
  procedure set (o : in out object;
                 components : components_t := (others=>zero)) is
  begin
    o.components := components;
  end set;

  -- setter that assigns value to specific component
  procedure set(o : in out object; index : positive; val : component_t) is
  begin
    o.components(index) := val;
  end set;

  -- getter that returns value of specific component
  function get(o : in object; index : positive) return component_t is
  begin
    return o.components(index);
  end get;

  -- returns the result of adding vector lhs to rhs
  function "+"(lhs, rhs: object) return object is
    result : object;
  begin
    for i in 1..dimension loop
      result.components(i) := lhs.components(i) + rhs.components(i);
    end loop;
    return result;
  end "+";

  -- returns the result of subtracting vector rhs from lhs
  function "-"(lhs, rhs: object) return object is
    result : object;
  begin
    for i in 1..dimension loop
      result.components(i) := lhs.components(i) - rhs.components(i);
    end loop;
    return result;
  end "-";

  -- returns the inner product of the two vectors
  function "*"(lhs, rhs: object) return component_t is
    result : component_t := zero;
  begin
    for i in 1..dimension loop
      result := result + lhs.components(i) * rhs.components(i);
    end loop;
    return result;
  end "*";

  -- returns the negative of the given object
  function "-"(o : object) return object is
    result : object;
  begin
    for i in 1..dimension loop
      result.components(i) := -o.components(i);
    end loop;
    return result;
  end "-";

  -- returns the sum of all components of the given vector object
  function sum(o : object) return component_t is
    result : component_t := zero;
  begin
    for i in 1..dimension loop
      result := result + o.components(i);
    end loop;
    return result;
  end sum;

  -- returns the length of vector
  function length(o : object) return positive is
  begin
    return o.components'Length;
  end length;

end ariane.maths.vector;
